/*============================================================================
  File:    dimensionBrowserfrm.cs

  Summary: Creates a windows to browse a given dimension.

  Date:    November 2006
------------------------------------------------------------------------------
  This file is part of the Microsoft SQL Server Code Samples.

  Copyright (C) Microsoft Corporation.  All rights reserved.

  This source code is intended only as a supplement to Microsoft
  Development Tools and/or on-line documentation.  See these other
  materials for detailed information regarding Microsoft code samples.

  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.
============================================================================*/


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using adoMdClient = Microsoft.AnalysisServices.AdomdClient;


namespace Microsoft.Samples.SqlServer
{
    
    public partial class dimensionBrowserfrm : Form
    {
        const int DimensionChildrenToLoad = 25;
        private adoMdClient.Dimension dimensionRoot;
        private ImageList icons = new ImageList();
        public adoMdClient.Dimension DimensionRoot
        {
            set 
            { 
                dimensionRoot = value;
                dimensionTree.Controls.Clear();
                dimensionTree.ImageList = icons;
                TreeNode dimensionRootNode = dimensionTree.Nodes.Add(dimensionRoot.Name);
                dimensionRootNode.Tag = dimensionRoot;
                dimensionTree.Select();
            }          
        }
        public dimensionBrowserfrm()
        {
            InitializeComponent();
            icons.ImageSize = new Size(32, 32);
            icons.Images.Add("Selected", Microsoft.Samples.SqlServer.VisualAids.Selected);
            icons.Images.Add("Dimension", Microsoft.Samples.SqlServer.VisualAids.Dimension);
            icons.Images.Add("Attribute", Microsoft.Samples.SqlServer.VisualAids.Attribute);
            icons.Images.Add("Hierarchy", Microsoft.Samples.SqlServer.VisualAids.Hierarchy);
            icons.Images.Add("ParentChild", Microsoft.Samples.SqlServer.VisualAids.ParentChild);
            icons.Images.Add("Ooops", Microsoft.Samples.SqlServer.VisualAids.Ooops);
            icons.Images.Add("Member", Microsoft.Samples.SqlServer.VisualAids.Member);
            icons.Images.Add("Level", Microsoft.Samples.SqlServer.VisualAids.Level);

        }

        private void dimensionTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TreeNode selectedNode = ((TreeView)sender).SelectedNode;
            if (selectedNode.Nodes.Count == 0)  //This is an unexplored node let's add Level and children Members
            {
                string selectedNodePath = selectedNode.FullPath;
                string[] pathElements = selectedNodePath.Split('\\');

                //  selectedNodePath structure:
                //  0    Dimension
                //  1        Hierarchy/Attribute
                //  2            Level
                //  3                Member
                //  4                    Level
                //  5                        Member
                //                              ...

                //Synchronize selected node with dimension object
                int treeDepth = pathElements.GetLength(0);
                Type nodeObjectType = selectedNode.Tag.GetType();
                string nodeObjectTypeName = nodeObjectType.FullName;

                switch (nodeObjectTypeName)
                {
                    case "Microsoft.AnalysisServices.AdomdClient.Dimension": //This is Dimension level, need to add hierarchies nodes
                        //  Report bug on this code
                        //foreach (adoMdClient.Hierarchy currentHierarchy in dimensionRoot.AttributeHierarchies)
                        //{
                        //    string currentHierarchyName = currentHierarchy.Name;
                        //    selectedNode.Nodes.Add(currentHierarchyName);
                        //    selectedNode.LastNode.ImageIndex = 0;
                        //}

                        //foreach (adoMdClient.Hierarchy currentHierarchy in dimensionRoot.Hierarchies)
                        //{
                        //    if (dimensionRoot.AttributeHierarchies.Find(currentHierarchy.Name) == null)
                        //    {
                        //        selectedNode.Nodes.Add(currentHierarchy.Name);
                        //        selectedNode.LastNode.ImageIndex = 1;
                        //    }
                        //}
                        selectedNode.ImageKey = "Dimension";
                        foreach (adoMdClient.Hierarchy currentHierarchy in dimensionRoot.Hierarchies)
                        {
                            selectedNode.Nodes.Add(currentHierarchy.Name);
                            selectedNode.LastNode.Tag = currentHierarchy;
                            switch (currentHierarchy.HierarchyOrigin)
                            {
                                case Microsoft.AnalysisServices.AdomdClient.HierarchyOrigin.AttributeHierarchy:
                                    selectedNode.LastNode.ImageKey = "Attribute";
                                    break;
                                case Microsoft.AnalysisServices.AdomdClient.HierarchyOrigin.UserHierarchy:
                                    selectedNode.LastNode.ImageKey = "Hierarchy";
                                    break;
                                case Microsoft.AnalysisServices.AdomdClient.HierarchyOrigin.ParentChildHierarchy:
                                    selectedNode.LastNode.ImageKey = "ParentChild";
                                    break;
                                default:
                                    selectedNode.LastNode.ImageKey = "Ooops";
                                    break;

                            }
                        }

                        break;

                    case "Microsoft.AnalysisServices.AdomdClient.Hierarchy": //This is Hierarchy/Attribute level, need to add first Level node (usually the 'All' level)
                        {
                            adoMdClient.Hierarchy currentHierarchy = (adoMdClient.Hierarchy)selectedNode.Tag;
                            if (currentHierarchy.Levels.Count > 0)
                            {
                                selectedNode.Nodes.Add(currentHierarchy.Levels[0].Name);
                                selectedNode.LastNode.Tag = currentHierarchy.Levels[0];
                                selectedNode.LastNode.ImageKey = "Level";
                            }
                        }

                        break;

                    case "Microsoft.AnalysisServices.AdomdClient.Level": //This is Hierarchy/Attribute level, need to add first Level node (usually the 'All' level)
                        adoMdClient.Level currentLevel = (adoMdClient.Level)selectedNode.Tag;
                        if (currentLevel.LevelType == Microsoft.AnalysisServices.AdomdClient.LevelTypeEnum.All)
                        {
                            adoMdClient.Member allMember = currentLevel.GetMembers(0,1)[0];
                            selectedNode.Nodes.Add(allMember.Name);
                            selectedNode.LastNode.Tag = allMember;
                            selectedNode.LastNode.ImageKey = "Member";

                        }
                        else
                        {
                            adoMdClient.Member parentMember = (adoMdClient.Member)selectedNode.Parent.Tag;   //immediate Parent is a Member
                            long childCount = parentMember.ChildCount;
                            long retrievedChildrenCount = 0;
                            do
                            {
                                adoMdClient.MemberCollection retrievedChildren = parentMember.GetChildren(retrievedChildrenCount, DimensionChildrenToLoad);
                                foreach (adoMdClient.Member currentMember in retrievedChildren)
                                {
                                    selectedNode.Nodes.Add(currentMember.Name);
                                    selectedNode.LastNode.Tag = currentMember;
                                    selectedNode.LastNode.ImageKey = "Member";
                                    retrievedChildrenCount++;
                                }

                            } while ((retrievedChildrenCount < childCount) && (MessageBox.Show(string.Concat("There are ", childCount.ToString(), " members in current dimension.\r\nFirst ", retrievedChildrenCount.ToString(), " already retrieved.\r\nDo you want next ", DimensionChildrenToLoad.ToString(), " members or less to be retrieved?"),
                                                                                               "Dimension Browser",
                                                                                               MessageBoxButtons.YesNo,
                                                                                               MessageBoxIcon.Question,
                                                                                               MessageBoxDefaultButton.Button2)==DialogResult.Yes));
                        }
                        break;

                    case "Microsoft.AnalysisServices.AdomdClient.Member":
                        {
                            adoMdClient.Member currentMember = (adoMdClient.Member)selectedNode.Tag;
                            
                            if (currentMember.ChildCount > 0)
                            {
                                adoMdClient.Member childMember = currentMember.GetChildren(0, 1)[0];
                                adoMdClient.Level nextLevel = childMember.ParentLevel;
                                selectedNode.Nodes.Add(nextLevel.Name);
                                selectedNode.LastNode.Tag = nextLevel;
                                selectedNode.LastNode.ImageKey = "Level";
                            }
                        }

                        break;


                    default:
                        MessageBox.Show(string.Concat("[", nodeObjectTypeName,"] is not an expected value"), "Dimension Browser", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;

                }

            }
            else
            {
                //Do nothing, keep node information as it's being displayed
                //ToDo: Refresh option
            }

        }
    }
}